#include "Instance.h"

VkInstance mini_engine::Instance::instance;
mini_engine::Instance *mini_engine::Instance::m_instnce = nullptr;

mini_engine::Instance::Instance()
{
}

vector<const char *> mini_engine::Instance::getRequiredExtensions()
{
    uint32_t glfwExtensionCount = 0;
    const char **glfwExtensions;
    glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
    vector<const char *> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
    return extensions;
}

void mini_engine::Instance::createInstance()
{
    cout << "create vulkan instance" << endl;

        VkApplicationInfo appInfo{};
        appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
        appInfo.pApplicationName = "Hello Triangle";
        appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
        appInfo.pEngineName = "No Engine";
        appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
        appInfo.apiVersion = VK_API_VERSION_1_0;

        VkInstanceCreateInfo createInfo{};
        createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
        createInfo.pApplicationInfo = &appInfo;

        auto extensions = Instance::getInstance()->getRequiredExtensions();
        createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
        createInfo.ppEnabledExtensionNames = extensions.data();

        // VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{};

        // if (enableValidationLayers) {
            createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
            createInfo.ppEnabledLayerNames = validationLayers.data();

            // populateDebugMessengerCreateInfo(debugCreateInfo);
            // createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &debugCreateInfo;
        // } 
        // else {
        //     createInfo.enabledLayerCount = 0;

        //     createInfo.pNext = nullptr;
        // }


        if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
            throw std::runtime_error("failed to create instance!");
        }
}

/**
 * 创建Vulkan实例
*/
mini_engine::Instance *mini_engine::Instance::getInstance()
{
    if (m_instnce == nullptr)
    {
        m_instnce = new Instance();
        static InstanceDestruction instanceDestruction;
    }
    return m_instnce;
}

mini_engine::Instance::~Instance()
{
}

mini_engine::Instance::InstanceDestruction::~InstanceDestruction()
{
    if (m_instnce != nullptr)
    {
        delete m_instnce;
        m_instnce = nullptr;
    }
}
